`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    09:56:27 03/31/2011 
// Design Name: 
// Module Name:    FIRfilter 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
// Parameters are N for input bit width, M for tap bit width, and K for num taps
// limited to N=M until true multiplier installed
//
//////////////////////////////////////////////////////////////////////////////////
module FIRfilter #(parameter N=8,M=8,K=8)(
    input [N-1:0] x_in,
    output [(N+M)-1:0] y_out,
    input clock,
	 input setTaps,
    input [(M*K)-1:0] taps
    );
	
	 //array of m-bit tap values
	 reg [M-1:0] tap [K-1:0] ;
	 
	 //array of registers to store the signal as it crosses the FIR
	 reg [N-1:0] signal [K-1:0];
	 
	 //wires for the outputs of the multiplication blocks
	 //so they can be concatenated into the adder block
	 wire [K*(N+M)-1:0] products;
	 
	 multiOperandAdder #(.NM(N+M), .K(K)) bigAdder (
		.operands(products),
		.s_out(y_out),
		.clock(clock));
	 
	genvar i, j;
	generate

	//instantiate the multipliers
	for(i=0; i<K; i=i+1) begin:mults
		csa_tree #(.N(N)) mult (signal[i], tap[i], products[(N+M)*(i+1)-1:(N+M)*i]);
		
	end
	
	//all of the clock based processing goes here
	//includes setting tap values (and clearing registers)
	//and normal 
	for(i=0; i<K; i=i+1) begin: tapLoop
		for(j=0; j<M; j=j+1) begin: bitLoop
			always @(posedge clock)begin
				if(setTaps == 1'b1)begin
					tap [i][j] <= taps[ i*M+j];
					signal[i][j] <= 1'b0;
				end else begin
					if(i == 0) begin
						signal[i] <= x_in;
					end else begin
						signal[i] <= signal[i-1];
					end
				end
			end//always
		end
	end

	endgenerate

endmodule
